package com.example.springaidemo.controller.case3;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.ChatClientMessageAggregator;
import org.springframework.ai.chat.client.ChatClientRequest;
import org.springframework.ai.chat.client.ChatClientResponse;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.client.advisor.api.CallAdvisorChain;
import org.springframework.ai.chat.client.advisor.api.StreamAdvisorChain;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

/**
 * @author stone
 * @date 2025/6/30 15:41
 */
@RestController
@RequestMapping("/case3")
@Slf4j
public class Case3Controller {

    @Resource
    @Qualifier("paramTextChatClient")
    private ChatClient chatClient;

    /**
     * 最简单的advisor=日志
     * <p>
     * org.springframework.ai.chat.client.advisor=debug
     */
    @GetMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> chat(@RequestParam("input") String input, @RequestParam("role") String role) {
        // input=聊一聊圆明园的故事吧，500字以内
        // role=邪恶女巫
        return this.chatClient.prompt()
                .system(promptSystemSpec -> promptSystemSpec.param("role", role))
                .advisors(new SimpleLoggerAdvisor())
                .user(input)
                .stream()
                .content();
    }

    /**
     * 自定义打印内容
     */
    @GetMapping(value = "/chat2",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> chat2(@RequestParam("input") String input, @RequestParam("role") String role) {
        // input=聊一聊圆明园的故事吧，500字以内
        // role=邪恶女巫
        return this.chatClient.prompt()
                .system(promptSystemSpec -> promptSystemSpec.param("role", role))
                .advisors(SimpleLoggerAdvisor.builder()
                        .requestToString(req -> "请求参数：" + req.prompt().getUserMessage().getText())
                        .responseToString(resp -> "响应参数：" + resp.getResult().getOutput().getText())
                        .build())
                .user(input)
                .stream()
                .content();
    }


    /**
     * 定义子类，自定义打印的
     */
    @GetMapping(value = "/chat3",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> chat3(@RequestParam("input") String input, @RequestParam("role") String role) {
        // input=聊一聊圆明园的故事吧，500字以内
        // role=邪恶女巫
        return this.chatClient.prompt()
                .system(promptSystemSpec -> promptSystemSpec.param("role", role))
                .advisors(new SimpleLogAdvisor())
                .user(input)
                .stream()
                .content();
    }

    /**
     * 自定义日志打印
     */
    public static class SimpleLogAdvisor extends SimpleLoggerAdvisor {

        public ChatClientResponse adviseCall(ChatClientRequest chatClientRequest, CallAdvisorChain callAdvisorChain) {
            log.info("自定义日志，请求参数：{}", chatClientRequest.prompt().getUserMessage().getText());
            ChatClientResponse chatClientResponse = super.adviseCall(chatClientRequest, callAdvisorChain);
            log.info("自定义日志，响应结果：{}", chatClientResponse.chatResponse().getResult().getOutput().getText());
            return chatClientResponse;
        }

        public Flux<ChatClientResponse> adviseStream(ChatClientRequest chatClientRequest, StreamAdvisorChain streamAdvisorChain) {
            log.info("自定义日志，请求参数：{}", chatClientRequest.prompt().getUserMessage().getText());
            Flux<ChatClientResponse> chatClientResponses = streamAdvisorChain.nextStream(chatClientRequest);
            return (new ChatClientMessageAggregator()).aggregateChatClientResponse(chatClientResponses, this::logResponse);
        }

        private void logResponse(ChatClientResponse chatClientResponse) {
            log.info("自定义日志，响应结果：{}", chatClientResponse.chatResponse().getResult().getOutput().getText());
        }
    }
}
